package br.usp.ime.entities;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.apache.commons.io.IOUtils;

import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;

@SuppressWarnings("serial")
@Entity
@Table(name = "submitted_files")
public class SubmittedFile implements Serializable {

    public Long id;
    public String fileName;
    public String description;
    public File file;
    public Date submissionDate;
    
    @ManyToOne (fetch=FetchType.EAGER)  
    @JoinColumn (name="TASK_ID")  
	public Task relatedTask;
    
    public User submittedBy;
    public Evaluation evaluation;

	public SubmittedFile() {
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "FILE_NAME")
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    @Column(name = "FILE_DESCRIPTION")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Lob
    public File getFile() {
        return file;
    }

    public void setFile(File saved) {
        this.file = saved;
    }

    @Column(name = "DUE_DATE")
    public Date getsubmissionDate() {
		return submissionDate;
	}

	public void setsubmissionDate(Date submissionDate) {
		this.submissionDate = submissionDate;
	}
    
	
    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, fetch=FetchType.LAZY)
    @JoinColumn(name = "TASK_ID")
    public Task getRelatedTask() {
        return relatedTask;
    }

    public void setRelatedTask(Task relatedTask) {
    	relatedTask.addSubmittedFile(this);
    	/*TODO: Remover da lista quando o SubmittedFile for apagado */
        this.relatedTask = relatedTask;
    }

    @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    @JoinColumn(name = "USER_LOGIN")
    public User getSubmittedBy() {
        return submittedBy;
    }

    public void setSubmittedBy(User submittedBy) {
    	submittedBy.addSubmittedFile(this);
    	/*TODO: Remover da lista quando o SubmittedFile for apagado */
        this.submittedBy = submittedBy;
    }
    
        
	public void createFile(UploadedFile uf) throws FileNotFoundException, IOException {
		String dest = "data/task" + relatedTask.getId().toString();
		dest = dest	+ "/" + submittedBy.getLogin() + "/";  
		createDirIfDoesNotExists(dest);
		File saved = new File(dest + uf.getFileName());
		IOUtils.copyLarge(uf.getFile(), new FileOutputStream(saved));
		setFile(saved);	
	}
	
	private void createDirIfDoesNotExists(String dest) {
		(new File(dest)).mkdirs();
	}

	@OneToOne(cascade = CascadeType.ALL)
	@JoinColumn(name = "FORM_ID")
	public Evaluation getEvaluation() {
		return evaluation;
	}

	public void setEvaluation(Evaluation evaluation) {
		this.evaluation = evaluation;
	}

}
